#include "ffmpeg_wrapper.h"
#include "logger.h"
#include <thread>
#include <chrono>

FFmpegWrapper::FFmpegWrapper() 
    : formatContext_(nullptr)
    , videoCodecContext_(nullptr)
    , audioCodecContext_(nullptr)
    , frame_(nullptr)
    , packet_(nullptr)
    , swsContext_(nullptr)
    , isInitialized_(false)
    , isPlaying_(false)
    , currentTime_(0.0)
    , duration_(0.0) {
}

FFmpegWrapper::~FFmpegWrapper() {
    cleanup();
}

bool FFmpegWrapper::initialize() {
    if (isInitialized_) {
        return true;
    }
    
    // 初始化FFmpeg
    av_register_all();
    avformat_network_init();
    
    // 分配格式上下文
    formatContext_ = avformat_alloc_context();
    if (!formatContext_) {
        Logger::getInstance().log(Logger::ERROR, "Failed to allocate format context");
        return false;
    }
    
    // 分配帧和包
    frame_ = av_frame_alloc();
    packet_ = av_packet_alloc();
    
    if (!frame_ || !packet_) {
        Logger::getInstance().log(Logger::ERROR, "Failed to allocate frame or packet");
        return false;
    }
    
    isInitialized_ = true;
    Logger::getInstance().log(Logger::INFO, "FFmpeg initialized successfully");
    return true;
}

bool FFmpegWrapper::openMedia(const std::string& filePath) {
    if (!isInitialized_) {
        Logger::getInstance().log(Logger::ERROR, "FFmpeg not initialized");
        return false;
    }
    
    // 打开输入文件
    int ret = avformat_open_input(&formatContext_, filePath.c_str(), nullptr, nullptr);
    if (ret < 0) {
        Logger::getInstance().log(Logger::ERROR, "Failed to open input file: " + filePath);
        return false;
    }
    
    // 查找流信息
    ret = avformat_find_stream_info(formatContext_, nullptr);
    if (ret < 0) {
        Logger::getInstance().log(Logger::ERROR, "Failed to find stream info");
        return false;
    }
    
    // 设置解码器
    if (!setupVideoDecoder() || !setupAudioDecoder()) {
        Logger::getInstance().log(Logger::ERROR, "Failed to setup decoders");
        return false;
    }
    
    // 获取时长
    if (formatContext_->duration != AV_NOPTS_VALUE) {
        duration_ = formatContext_->duration / (double)AV_TIME_BASE;
    }
    
    Logger::getInstance().log(Logger::INFO, "Media opened successfully: " + filePath);
    return true;
}

FFmpegWrapper::MediaInfo FFmpegWrapper::getMediaInfo() {
    MediaInfo info = {0, 0, 0.0, 0, ""};
    
    if (!formatContext_) {
        return info;
    }
    
    // 查找视频流
    int videoStreamIndex = -1;
    for (unsigned int i = 0; i < formatContext_->nb_streams; i++) {
        if (formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }
    
    if (videoStreamIndex >= 0) {
        AVStream* videoStream = formatContext_->streams[videoStreamIndex];
        info.width = videoStream->codecpar->width;
        info.height = videoStream->codecpar->height;
        info.duration = duration_;
        info.bitrate = formatContext_->bit_rate;
        
        // 获取编解码器名称
        AVCodec* codec = avcodec_find_decoder(videoStream->codecpar->codec_id);
        if (codec) {
            info.codec = codec->name;
        }
    }
    
    return info;
}

bool FFmpegWrapper::setupVideoDecoder() {
    // 查找视频流
    int videoStreamIndex = -1;
    for (unsigned int i = 0; i < formatContext_->nb_streams; i++) {
        if (formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_VIDEO) {
            videoStreamIndex = i;
            break;
        }
    }
    
    if (videoStreamIndex < 0) {
        Logger::getInstance().log(Logger::WARNING, "No video stream found");
        return true; // 没有视频流不算错误
    }
    
    // 获取解码器
    AVCodec* codec = avcodec_find_decoder(formatContext_->streams[videoStreamIndex]->codecpar->codec_id);
    if (!codec) {
        Logger::getInstance().log(Logger::ERROR, "Video codec not found");
        return false;
    }
    
    // 创建解码器上下文
    videoCodecContext_ = avcodec_alloc_context3(codec);
    if (!videoCodecContext_) {
        Logger::getInstance().log(Logger::ERROR, "Failed to allocate video codec context");
        return false;
    }
    
    // 复制参数
    int ret = avcodec_parameters_to_context(videoCodecContext_, 
                                           formatContext_->streams[videoStreamIndex]->codecpar);
    if (ret < 0) {
        Logger::getInstance().log(Logger::ERROR, "Failed to copy codec parameters");
        return false;
    }
    
    // 打开解码器
    ret = avcodec_open2(videoCodecContext_, codec, nullptr);
    if (ret < 0) {
        Logger::getInstance().log(Logger::ERROR, "Failed to open video codec");
        return false;
    }
    
    Logger::getInstance().log(Logger::INFO, "Video decoder setup successfully");
    return true;
}

bool FFmpegWrapper::setupAudioDecoder() {
    // 查找音频流
    int audioStreamIndex = -1;
    for (unsigned int i = 0; i < formatContext_->nb_streams; i++) {
        if (formatContext_->streams[i]->codecpar->codec_type == AVMEDIA_TYPE_AUDIO) {
            audioStreamIndex = i;
            break;
        }
    }
    
    if (audioStreamIndex < 0) {
        Logger::getInstance().log(Logger::WARNING, "No audio stream found");
        return true; // 没有音频流不算错误
    }
    
    // 获取解码器
    AVCodec* codec = avcodec_find_decoder(formatContext_->streams[audioStreamIndex]->codecpar->codec_id);
    if (!codec) {
        Logger::getInstance().log(Logger::ERROR, "Audio codec not found");
        return false;
    }
    
    // 创建解码器上下文
    audioCodecContext_ = avcodec_alloc_context3(codec);
    if (!audioCodecContext_) {
        Logger::getInstance().log(Logger::ERROR, "Failed to allocate audio codec context");
        return false;
    }
    
    // 复制参数
    int ret = avcodec_parameters_to_context(audioCodecContext_, 
                                           formatContext_->streams[audioStreamIndex]->codecpar);
    if (ret < 0) {
        Logger::getInstance().log(Logger::ERROR, "Failed to copy audio codec parameters");
        return false;
    }
    
    // 打开解码器
    ret = avcodec_open2(audioCodecContext_, codec, nullptr);
    if (ret < 0) {
        Logger::getInstance().log(Logger::ERROR, "Failed to open audio codec");
        return false;
    }
    
    Logger::getInstance().log(Logger::INFO, "Audio decoder setup successfully");
    return true;
}

bool FFmpegWrapper::play() {
    if (!isInitialized_ || !formatContext_) {
        return false;
    }
    
    isPlaying_ = true;
    Logger::getInstance().log(Logger::INFO, "Playback started");
    return true;
}

bool FFmpegWrapper::pause() {
    isPlaying_ = false;
    Logger::getInstance().log(Logger::INFO, "Playback paused");
    return true;
}

bool FFmpegWrapper::stop() {
    isPlaying_ = false;
    currentTime_ = 0.0;
    Logger::getInstance().log(Logger::INFO, "Playback stopped");
    return true;
}

bool FFmpegWrapper::seek(double time) {
    if (!formatContext_) {
        return false;
    }
    
    int64_t timestamp = (int64_t)(time * AV_TIME_BASE);
    int ret = av_seek_frame(formatContext_, -1, timestamp, AVSEEK_FLAG_BACKWARD);
    if (ret < 0) {
        Logger::getInstance().log(Logger::ERROR, "Failed to seek");
        return false;
    }
    
    currentTime_ = time;
    Logger::getInstance().log(Logger::INFO, "Seeked to: " + std::to_string(time));
    return true;
}

void FFmpegWrapper::setVolume(double volume) {
    // 音量控制实现
    Logger::getInstance().log(Logger::INFO, "Volume set to: " + std::to_string(volume));
}

void FFmpegWrapper::cleanup() {
    if (swsContext_) {
        sws_freeContext(swsContext_);
        swsContext_ = nullptr;
    }
    
    cleanupCodecContexts();
    
    if (frame_) {
        av_frame_free(&frame_);
    }
    
    if (packet_) {
        av_packet_free(&packet_);
    }
    
    if (formatContext_) {
        avformat_close_input(&formatContext_);
    }
    
    isInitialized_ = false;
    isPlaying_ = false;
}

void FFmpegWrapper::cleanupCodecContexts() {
    if (videoCodecContext_) {
        avcodec_free_context(&videoCodecContext_);
    }
    
    if (audioCodecContext_) {
        avcodec_free_context(&audioCodecContext_);
    }
}
